package com.muyu.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.muyu.common.core.enums.SysNormalDisableEnum;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.core.web.page.PageQueryModel;
import com.muyu.common.security.utils.DictUtils;
import com.muyu.common.system.domain.SysDictData;
import com.muyu.system.domain.model.SysDictDataAddModel;
import com.muyu.system.domain.model.SysDictDataPageQueryModel;
import com.muyu.system.domain.model.SysDictDataUpdModel;
import com.muyu.system.mapper.SysDictDataMapper;
import com.muyu.system.service.SysDictDataService;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;

/**
 * 字典 业务层处理
 *
 * @author muyu
 */
@Service
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements SysDictDataService {


    /**
     * 根据条件分页查询字典数据
     *
     * @param pageQueryModel 字典数据信息
     *
     * @return 字典数据集合信息
     */
    @Override
    public PageQueryModel<SysDictData> selectDictDataList (SysDictDataPageQueryModel pageQueryModel) {
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StringUtils.isNotNull(pageQueryModel.getDictType()),SysDictData::getDictType, pageQueryModel.getDictType());
        lambdaQueryWrapper.like(StringUtils.isNotNull(pageQueryModel.getDictLabel()),SysDictData::getDictLabel, pageQueryModel.getDictLabel());
        lambdaQueryWrapper.eq(StringUtils.isNotNull(pageQueryModel.getStatus()),SysDictData::getStatus, pageQueryModel.getStatus());
        Page<SysDictData> sysDictDataPage = this.page(pageQueryModel.buildPage(), lambdaQueryWrapper);
        return PageQueryModel.of(sysDictDataPage);
    }

    /**
     * 根据字典类型和字典键值查询字典数据信息
     *
     * @param dictType  字典类型
     * @param dictValue 字典键值
     *
     * @return 字典标签
     */
    @Override
    public String selectDictLabel (String dictType, String dictValue) {
        Assert.notNull(dictType, "字典类型 不可为空");
        Assert.notNull(dictValue, "字典键值 不可为空");
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDictData::getDictType, dictType);
        lambdaQueryWrapper.eq(SysDictData::getDictValue, dictValue);
        SysDictData sysDictData = this.getOne(lambdaQueryWrapper);
        return sysDictData.getDictLabel();
    }

    /**
     * 根据字典数据ID查询信息
     *
     * @param dictCode 字典数据ID
     *
     * @return 字典数据
     */
    @Override
    public SysDictData getOneById(Long dictCode) {
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<SysDictData>()
                .eq(SysDictData::getDictCode, dictCode);
        return this.getOne(lambdaQueryWrapper);
    }

    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     */
    @Override
    public void deleteDictDataByIds (List<Long> dictCodes) {
        for (Long dictCode : dictCodes) {
            SysDictData data = this.getOneById(dictCode);
            LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(SysDictData::getDictCode, dictCode);
            this.remove(lambdaQueryWrapper);
            List<SysDictData> sysDictDataList = this.selectDictDataByType(data.getDictType());
            DictUtils.setDictCache(data.getDictType(), sysDictDataList);
        }
    }

    /**
     * 新增保存字典数据信息
     *
     * @param sysDictDataAddModel 字典数据信息
     */
    @Override
    public void insertDictData (SysDictDataAddModel sysDictDataAddModel) {
        SysDictData sysDictData = SysDictData.builder()
                .dictCode(sysDictDataAddModel.getDictCode())
                .dictSort(sysDictDataAddModel.getDictSort())
                .dictLabel(sysDictDataAddModel.getDictLabel())
                .dictValue(sysDictDataAddModel.getDictValue())
                .dictType(sysDictDataAddModel.getDictType())
                .cssClass(sysDictDataAddModel.getCssClass())
                .listClass(sysDictDataAddModel.getListClass())
                .isDefault(sysDictDataAddModel.getIsDefault())
                .status(sysDictDataAddModel.getStatus())
                .build();
        if (this.save(sysDictData)) {
            List<SysDictData> dictDataList = this.selectDictDataByType(sysDictData.getDictType());
            DictUtils.setDictCache(sysDictData.getDictType(), dictDataList);
        }
    }

    /**
     * 修改保存字典数据信息
     *
     * @param sysDictDataUpdModel 字典数据信息
     */
    @Override
    public void updateDictData (SysDictDataUpdModel sysDictDataUpdModel) {
        SysDictData sysDictData = SysDictData.builder()
                .dictCode(sysDictDataUpdModel.getDictCode())
                .dictSort(sysDictDataUpdModel.getDictSort())
                .dictLabel(sysDictDataUpdModel.getDictLabel())
                .dictValue(sysDictDataUpdModel.getDictValue())
                .dictType(sysDictDataUpdModel.getDictType())
                .cssClass(sysDictDataUpdModel.getCssClass())
                .listClass(sysDictDataUpdModel.getListClass())
                .isDefault(sysDictDataUpdModel.getIsDefault())
                .status(sysDictDataUpdModel.getStatus())
                .build();
        if (this.updateById(sysDictData)) {
            List<SysDictData> dictDataList = this.selectDictDataByType(sysDictData.getDictType());
            DictUtils.setDictCache(sysDictData.getDictType(), dictDataList);
        }
    }

    @Override
    public PageQueryModel<SysDictData> pageQuery(SysDictDataPageQueryModel sysDictdataPageQueryModel) {
        LambdaQueryWrapper<SysDictData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(sysDictdataPageQueryModel.getDictType()),SysDictData::getDictType, sysDictdataPageQueryModel.getDictType());
        queryWrapper.like(StringUtils.isNotEmpty(sysDictdataPageQueryModel.getDictLabel()),SysDictData::getDictLabel, sysDictdataPageQueryModel.getDictLabel());
        queryWrapper.eq(StringUtils.isNotEmpty(sysDictdataPageQueryModel.getStatus()),SysDictData::getDictType, sysDictdataPageQueryModel.getStatus());
        Page<SysDictData> page = this.page(sysDictdataPageQueryModel.buildPage(), queryWrapper);
        return PageQueryModel.of(page);
    }

    /**
     * 查询所有非禁用的字典
     * @return 非禁用字典集合
     */
    @Override
    public List<SysDictData> findAllByEnable() {
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDictData::getStatus, SysNormalDisableEnum.ENABLE.getCode());
        return this.list(lambdaQueryWrapper);
    }

    /**
     * 通过旧的字典类型修改为新字典类型
     *
     * @param oldDictType 旧字典类型
     * @param newDictType 新字典类型
     */
    @Override
    public void updateDictDataType(String oldDictType, String newDictType) {
        Assert.notNull(oldDictType, "旧字典类型不可为空");
        Assert.notNull(newDictType, "新字典类型不可为空");
        LambdaUpdateWrapper<SysDictData> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.set(SysDictData::getDictType, newDictType);
        lambdaUpdateWrapper.eq(SysDictData::getDictType, oldDictType);
        this.update(lambdaUpdateWrapper);
    }

    /**
     * 通过字典类型获取旗下所有字典值
     *
     * @param dictType 字典类型
     * @return 所有字典值集合
     */
    @Override
    public List<SysDictData> selectDictDataByType(String dictType) {
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDictData::getDictType, dictType);
        lambdaQueryWrapper.eq(SysDictData::getStatus, SysNormalDisableEnum.DISABLE.getCode());
        lambdaQueryWrapper.orderByAsc(SysDictData::getDictSort);
        return this.list(lambdaQueryWrapper);
    }

    /**
     * 根据字典类型查询字典下总数
     *
     * @param dictType 字典类型
     * @return 总数
     */
    @Override
    public long countDictDataByType(String dictType) {
        Assert.notNull(dictType, "字典类型不可为空");
        LambdaQueryWrapper<SysDictData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysDictData::getDictType, dictType);
        return this.count(lambdaQueryWrapper);
    }

    /**
     * 根据字典类型查询是否有子集
     *
     * @param dictType 字典类型
     * @return 含有：true 不含有：false
     */
    @Override
    public boolean isChildByType(String dictType) {
        return countDictDataByType(dictType) > 0;
    }
}
